<?php

/**
 * Creating HTML to visualizise data about subdivisions
 * 
 * @author Aldis Rameika
 */
class LoadViewDesign {
    const DIAGRAM_MODE_ADMINISTRATED = 0;
    const DIAGRAM_MODE_TIME = 1;

    /**
     * Table for subdivisions
     * 
     * @param array $dates          [date]=>boolean is predicted
     * @param array $subdivisions   [code]=>name
     * @param array $time_groups    [subdivision][date]=>TimeGroup
     * @param $mode                 see TABLE_MODE_*
     */
    public static function table_sub($dates, $subdivisions, $time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED, $width = null) {
        global $row_index;
        if ($width) {
            $width = intval($width);
            $additional = " style='width: {$width}px;' ";
        } else {
            $additional = '';
        }
        ?><div <?=$additional;?> class="data_table"><table class="data_table" border="0">
        <?php
        self::table_header($dates, 'Padalinys | Laikotarpis');
        foreach ($time_groups as $subdivsion_code => $row) {
            $subdivision_name = htmlspecialchars($subdivisions[$subdivsion_code]);
            $row_class = $row_index ? ' class="r1"' : '';
            $row_index = $row_index ? false : true;
            echo "<tr $row_class><td class='head_column'>$subdivision_name</td>";
            foreach ($row as $date => $time_group) {
                $administrated = $time_group->sum_administrated();
                $time = $time_group->sum_time_used();
                $predicted = $time_group->predicted ? 'predicted' : '';
                if ($mode == self::DIAGRAM_MODE_ADMINISTRATED) {
                    if ($predicted) {
                        $predicted = " class='$predicted'";
                    }
                    echo "<td $predicted title='$subdivision_name'>";
                    echo "<span class='addministrated'>$administrated</span><br/>";
                    echo '</td>';
                } else {
                    //echo "<td title='$subdivision_name' class='time $predicted'>$time</td>";
		    echo "<td title='$subdivision_name'>$time</td>";
                }
            }
            echo '</tr>';
        }
        ?>
            </table></div>
        <?php
    }

    /**
     * Comparison table for subdivisions
     * 
     * @param array $dates          [date]=>boolean is predicted
     * @param array $subdivisions   [code]=>name
     * @param array $time_groups1   [subdivision][date]=>TimeGroup
     * @param array $time_groups2   [subdivision][date]=>TimeGroup
     * @param $mode                 see TABLE_MODE_*
     */
    public static function table_compare_sub($dates, $subdivisions, $time_groups1, $time_groups2) {
        global $row_index;
        $max_border = self::get_max_predicted_sub($time_groups1, $time_groups2) / 10;
        ?><div class="data_table"><table class="data_table" border="0">
            <?php
            self::table_header($dates, 'Padalinys | Laikotarpis');
            foreach ($time_groups1 as $subdivsion_code => $row) {
                $subdivision_name = htmlspecialchars($subdivisions[$subdivsion_code]);
                $row_class = $row_index ? ' class="r1"' : '';
                $row_index = $row_index ? false : true;
                echo "<tr $row_class><td class='head_column'>$subdivision_name</td>";
                foreach ($dates as $date=>$predicted) {
                    $time_group1 = $row[$date];
                    $administrated1 = $time_group1->sum_administrated();
                    $time1 = $time_group1->sum_time_used();

                    $time_group2 = $time_groups2[$subdivsion_code][$date];
                    $administrated2 = $time_group2->sum_administrated();
                    $time2 = $time_group2->sum_time_used();

                    $administrated = self::percent_diff($administrated1, $administrated2, true, $max_border);
                    $time = self::percent_diff($time1, $time2, true, $max_border);

                    $predicted = $predicted ? 'predicted' : '';
                    if ($predicted) {
                        $predicted = " class='$predicted'";
                    }
                    echo "<td $predicted >";
                    echo "<span class='addministrated'>$administrated</span><br/>";
                    echo "<span class='time'>$time</span><br/>";
                    echo '</td>';
                }
                echo '</tr>';
            }
            ?>
            </table></div>
        <?php
    }

    private static function get_max_predicted_sub($time_groups1, $time_groups2) {
        $max = 1;
        foreach ($time_groups1 as $subdivsion_code => $row) {
            foreach ($row as $date => $time_group1) {
                $administrated1 = $time_group1->sum_administrated();
                $time1 = $time_group1->sum_time_used();

                $time_group2 = $time_groups2[$subdivsion_code][$date];
                $administrated2 = $time_group2->sum_administrated();
                $time2 = $time_group2->sum_time_used();

                $administrated = self::percent_diff($administrated1, $administrated2, false);
                $time = self::percent_diff($time1, $time2, false);
                $max = max($administrated, $time, $max);
            }
        }
        return $max;
    }

    public static function table_compare_is($dates, $is_names, $is_time_groups1, $is_time_groups2) {
        global $row_index;
        $max_border = self::get_max_predicted_is($is_time_groups1, $is_time_groups2) / 10;
        ?><div class="data_table"><table class="data_table" border="0">
            <?php
            self::table_header($dates, 'Informacine sistema | Laikotarpis');
            foreach ($is_time_groups1 as $is => $row) {
                $is_name = htmlspecialchars($is_names[$is]);
                $row_class = $row_index ? ' class="r1"' : '';
                $row_index = $row_index ? false : true;
                echo "<tr $row_class><td class='head_column'>$is_name</td>";
                foreach ($dates as $date=>$predicted) {
                    $is_time_group1 = $row[$date];
                    $administrated1 = $is_time_group1->sum_n;
                    $time1 = $is_time_group1->sum_time;

                    $time_group2 = $is_time_groups2[$is][$date];
                    $administrated2 = $time_group2->sum_n;
                    $time2 = $time_group2->sum_time;

                    $administrated = self::percent_diff($administrated1, $administrated2, true, $max_border);
                    $time = self::percent_diff($time1, $time2, true, $max_border);

                    $predicted = $predicted ? 'predicted' : '';
                    if ($predicted) {
                        $predicted = " class='$predicted'";
                    }
                    echo "<td $predicted>";
                    echo "<span class='addministrated'>$administrated</span><br/>";
                    echo "<span class='time'>$time</span><br/>";
                    echo '</td>';
                }
                echo '</tr>';
            }
            ?>
            </table></div>
        <?php
    }

    private static function get_max_predicted_is($is_time_groups1, $is_time_groups2) {
        $max = 1;
        foreach ($is_time_groups1 as $is => $row) {
            foreach ($row as $date => $is_time_group1) {
                $administrated1 = $is_time_group1->sum_n;
                $time1 = $is_time_group1->sum_time;

                $time_group2 = $is_time_groups2[$is][$date];
                $administrated2 = $time_group2->sum_n;
                $time2 = $time_group2->sum_time;

                $administrated = self::percent_diff($administrated1, $administrated2, false);
                $time = self::percent_diff($time1, $time2, false);
                $max = max($administrated, $time, $max);
            }
        }
        return $max;
    }

    private static function percent_diff($value1, $value2, $use_html = true, $max_border = null) {
        if ($value1 == 0 && $value2 != 0) {
            return $value2;
        } else if ($value2 == 0 && $value1 != 0) {
            return $value1;
        } else if ($value1 < $value2) {
            $value = ($value2 / $value1) * 100;
        } else if ($value1 > $value2) {
            $value = -($value1 / $value2) * 100;
        } else {
            if ($use_html) {
                return '<span class="zero">0%</span>';
            } else {
                return 0;
            }
        }
        if (abs($value) < 100) {
            $color = dechex($value * 128);
        } else {
            $color = '88';
        }
        if ($value > 0) {
            $color = $color . '2222';
            $value = '+' . round($value, 1);
        } else {
            $color = '22' . $color . '22';
            $value = round($value, 1);
        }
        if ($use_html) {
            if ($max_border == null) {
                $max_border = 20;
            }
            $border_size = round(abs($value) / $max_border);
            return "<span style='border-left: {$border_size}px solid #$color;'>$value%</span>";
        } else {
            return $value;
        }
    }

    public static function table_is($dates, $is_names, $is_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED, $width = null) {
        global $row_index;
        if ($width) {
            $width = intval($width);
            $additional = " style='width: {$width}px;' ";
        } else {
            $additional = '';
        }
        ?><div <?=$additional;?> class="data_table"><table class="data_table" border="0">
            <?php
            self::table_header($dates, 'IS | Laikotarpis');

            foreach ($is_time_groups as $is_code => $row) {
                $is_name = htmlspecialchars($is_names[$is_code]);
                $row_class = $row_index ? ' class="r1"' : '';
                $row_index = $row_index ? false : true;
                echo "<tr $row_class><td class='head_column'>$is_name</td>";
                foreach ($row as $date => $is_time_group) {
                    $used = $is_time_group->sum_n;
                    $time = $is_time_group->sum_time;
                    $predicted = $is_time_group->predicted ? ' class="predicted"' : '';
                    echo "<td $predicted title='$is_name'>";
                    if ($mode == self::DIAGRAM_MODE_TIME) {
                        echo "<span class='time'>$time</span>";
                    } else {
                        echo "<span class='administrated'>$used</span>";
                    }
                    echo '</td>';
                }
                echo '</tr>';
            }
            ?>
            </table></div>
        <?php
    }

    private static function table_header($dates, $informationCell) {
        $informationCell = htmlspecialchars($informationCell);
        ?><thead><tr class="head_row"><?php
        echo "<th class='corner'>$informationCell</th>";
        foreach ($dates as $date => $is_predicted) {
            $time = htmlspecialchars($date);
            $date = date('Y m', strtotime($date));
            $class = $is_predicted ? 'class="predicted"' : '';
            echo "<th $class>$date</th>";
        }
        ?></tr></thead><?php
    }

    public static function php_linear_sub($dates, $subdivisions, $sub_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED, $cache_date = null, $width = 1000, $height = 300, $file='sub_%MODE%.gif', $show_legend = true) {
        $time_groups = self::sub_to_array($sub_time_groups, $mode);
        ?><div class="php_diagram"><?
        $file = str_replace('%MODE%', $mode, $file);
        $colors = self::php_liner($file, $dates, $subdivisions, $time_groups, $mode, $width, $height, $cache_date);
        ?></div>
        <?
        if ($show_legend) {
            self::legend($subdivisions, $colors);
        }
    }
    
    public static function php_linear_is($dates, $is, $is_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED, $cache_date = null, $width = 1000, $height = 300, $file='sub_%MODE%.gif', $show_legend = true) {
        $time_groups = self::is_to_array($is_time_groups, $mode);
        ?><div class="php_diagram"><?
        $file = str_replace('%MODE%', $mode, $file);
        $colors = self::php_liner($file, $dates, $is, $time_groups, $mode, $width, $height, $cache_date);
        ?></div>
        <?
        if ($show_legend) {
            self::legend($is, $colors);
        }
    }
    
    private static function legend($series, $colors) {
        ?>
        <div class="legend">
            <?php
            foreach ($series as $code => $name) {
                $name = htmlspecialchars($name);
                $short_code = strtolower(htmlspecialchars($code));
                echo "<div class=\"shallow legend_line_$short_code\" style='border-left: 10px solid #{$colors[$code]}'>$name</div>";
            }
            ?>
        </div>
        <?
    }

    private static function php_liner($file_name, $dates, $line_names, $time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED, $width = 1000, $height = 300, $cache_date = null) {
        global $php_liner_diagram_id;
        $php_liner_diagram_id++;
        $cache_directory = dirname(dirname(dirname(dirname(__FILE__)))) . "/Cache";
        require_once 'GUI/Diagrams/diagrams_processing.php';
        $colors = Diagrams::get_colors($time_groups);
        if (count($colors) == 2) {
            $keys = array_keys($colors);
            $colors[$keys[0]] = '008800';
            $colors[$keys[1]] = '880088';
        }
        $file = "$cache_directory/$file_name";
        $new_file = Diagrams::draw($time_groups, $dates, $file, $colors, $points, $cache_date, $width, $height);
        if ($file != $new_file) {
            $link = "GUI/Diagrams/translate.php?f=$file_name";
        } else {
            $link = "Cache/$file_name";
        }
        $file_name = htmlspecialchars($file_name);
        $diagram_id = "php_diagram_$php_liner_diagram_id";
        $points = self::get_tooltip_points($points);
        ?>
        <img id="<?= $diagram_id; ?>" src="<?= $link; ?>" alt="Diagrama" width="<?= $width; ?>" height="<?= $height; ?>"/>
        <script type="text/javascript">
            $(document).ready(function() {
                iniciate_diagram_labels('#<?= $diagram_id; ?>', <?= $points; ?>);
            })
        </script>
        <?
        return $colors;
    }

    private static function get_tooltip_points($points) {
        $result = array();
        foreach ($points as $point) {
            $point_result = array();
            foreach ($point as $name => $value) {
                if (!is_numeric($value)) {
                    $value = "'$value'";
                }
                $point_result[] = "$name: $value";
            }
            $result[] = '{' . implode(', ', $point_result) . '}';
        }
        return '[' . implode(', ', $result) . ']';
    }

    /**
     * @param array $time_groups    [subdivision][date]=>TimeGroup
     * @return array                [subdivision][date]=>scalar value according to mode
     */
    private static function sub_to_array($sub_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $result = array();
        foreach ($sub_time_groups as $subdivision => $line) {
            foreach ($line as $date => $time_group) {
                switch ($mode) {
                    case self::DIAGRAM_MODE_TIME:
                        $value = $time_group->sum_time_used();
                        break;
                    default:
                        $value = $time_group->sum_administrated();
                }
                $result[$subdivision][$date] = $value;
            }
        }
        return $result;
    }

    /**
     * @param array $time_groups    [subdivision][date]=>TimeGroup
     * @return array                [subdivision][date]=>scalar value according to mode
     */
    private static function is_to_array($is_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $result = array();
        foreach ($is_time_groups as $is => $line) {
            foreach ($line as $date => $time_group) {
                switch ($mode) {
                    case self::DIAGRAM_MODE_TIME:
                        $value = $time_group->sum_time_used();
                        break;
                    default:
                        $value = $time_group->sum_administrated();
                }
                $result[$is][$date] = $value;
            }
        }
        return $result;
    }

    /**
     * Paints a dotted sub chart 
     * @param array $dates              [date]=>boolean is predicted
     * @param array $subdivisions       [code]=>name
     * @param array $sub_time_groups    [subdivision][date]=>TimeGroup
     * @param $mode                     see DIAGRAM_MODE_*
     */
    public static function dotted_sub($dates, $subdivisions, $sub_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $column_count = count($sub_time_groups);
        $row_count = self::get_row_count($sub_time_groups);
        ?>
        <div id="dotted_sub_table">
            <table class="dotted_sub_table">
                <?
                self::generate_sub_data($subdivisions, $sub_time_groups, $mode);
                self::generate_headers($dates);
                ?>
            </table>
        </div>
        <?php
    }

    /*
     * Paints a dotted IS chart 
     * @param array $dates              [date]=>boolean is predicted
     * @param array $is_names           [code]=>name
     * @param array $is_time_groups     [subdivision][date]=>TimeGroup
     * @param $mode                     see DIAGRAM_MODE_*
     */

    public static function dotted_is($dates, $is_names, $is_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $column_count = count($is_time_groups);
        $row_count = self::get_row_count($is_time_groups);
        ?>
        <div id="dotted_is_table">
            <table class="dotted_is_table">
                <?
                self::generate_is_data($is_names, $is_time_groups, $mode);
                self::generate_headers($dates);
                ?>
            </table>
        </div>
        <?php
    }

    /**
     * Paints a linear SUB chart 
     * @param array $dates              [date]=>boolean is predicted
     * @param array $subdivisions       [code]=>name
     * @param array $sub_time_groups    [subdivision][date]=>TimeGroup
     * @param $mode                     see DIAGRAM_MODE_*
     */
    public static function linear_sub($dates, $subdivisions, $sub_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $column_count = count($sub_time_groups);
        $row_count = self::get_row_count($sub_time_groups);
        ?>
        <script>
            $('#status').text('Atnaujinamos diagramos');
            $('#status').css('display', 'block');

                                                                                                                    
            var chart;
            $(document).ready(function() {
                $('#status').text('Atnaujinamos diagramos');
                $('#status').css('display', 'block');
                                                                                                                        
                chart = new Highcharts.Chart(
        <?
        echo "{\n";
        echo self::generate_chart("linear_sub_table", $row_count * 40) . ",\n";
        echo self::generate_colors() . ",\n";
        echo self::generate_title("") . ",\n";
        echo self::generate_subtitle("") . ",\n";
        echo self::generate_xAxis($dates) . ",\n";
        if ($mode == self::DIAGRAM_MODE_TIME) {
            echo self::generate_yAxis("Darbo laikas valandomis") . ",\n";
        } else {
            echo self::generate_yAxis("Paraišku skaicius") . ",\n";
        }
        echo self::generate_tooltip() . ",\n";
        echo self::generate_sub_series($subdivisions, $sub_time_groups, $mode) . "\n";
        echo " }";
        ?>);	
                $('#status').css('display', 'none');
                                                                                                                    
            });
        </script>
        <div id="linear_sub_table"></div>
        <?php
    }

    /**
     * Paints a linear SUB chart 
     * @param array $dates              [date]=>boolean is predicted
     * @param array $subdivisions       [code]=>name
     * @param array $sub_time_groups    [subdivision][date]=>TimeGroup
     * @param $mode                     see DIAGRAM_MODE_*
     */
    public static function linear_sub2($dates, $subdivisions, $sub_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        global $buffDiagramIndex;
        $column_count = count($sub_time_groups);
        $row_count = self::get_row_count($sub_time_groups);
        // TODO: automatinis grazinimass (ciklas4)
        $name = 'diagram' . (++$buffDiagramIndex);
        $size = '1600x400';
        $predicetd = array_search(true, $dates);
        $date_text = array_keys($dates);
        $predicetd = array_search($predicetd, $date_text);
        ?>
        <div class="buff_diagram" id="div_<?= $name; ?>"><pre><canvas id="<?= $name; ?>"></canvas></pre></div>
        <script type="text/javascript">
            $('#status').text('Atnaujinamos diagramos');
            $('#status').css('display', 'block');
                                                                                                                    
            var chart;
            $(document).ready(function() {
                $('#status').text('Atnaujinamos diagramos');
                $('#status').css('display', 'block');
                                                                                                                    
                /* Data */
                var chartData = {
        <?
        echo self::generate_xAxis($dates) . ",\n";
        if ($mode == self::DIAGRAM_MODE_TIME) {
            echo self::generate_yAxis("Darbo laikas valandomis") . ",\n";
        } else {
            echo self::generate_yAxis("Paraišku skaicius") . ",\n";
        }
        echo self::generate_sub_series($subdivisions, $sub_time_groups, $mode) . "\n";
        echo " ";
        ?>};
                                                                                                                        
                    /* Drawing */
                    var g = new Bluff.Line('<?= $name; ?>', '<?= $size; ?>');
                    g.theme_greyscale();

                    g.hide_dots = true;
                    g.title_font_size = '5px';
                    g.legend_font_size = '8px';
                    g.marker_font_size = '3px';

                    g.hide_legend = true;
                    g.hide_title = true;
                                                                                                                        
                    g.top_margin = 2;
                    g.left_margin = 2;
                    g.right_margin = 2;
                    g.bottom_margin = 15;
                    g.tooltips = true;

                    g.labels = [];
                    for(var i in chartData.xAxis.categories) {
                        var date = chartData.xAxis.categories[i].replace(' ', '\n');
                        date = date.substring(0, 2) + "\n" + date.substring(2);
                        g.labels.push(date);
                                                                                                                            
                    }

                    for(var i in chartData.series) {
                        var line = chartData.series[i];
                        g.data(line.name, line.data);
                    }

                    g.draw();
                                                                                                                        
                    var month = 0;
                    $.each( $('#div_<?= $name; ?> div.bluff-text'), function(i, div) {
                        if (div.innerHTML.indexOf('\n') != -1) {
                            var date = div.innerHTML.substring(0, 2) + div.innerHTML.substring(3, 5) + ' ' + div.innerHTML.substring(6);
                            div.title = date;
                            if (month >= <?= $predicetd; ?>) {
                                $(div).addClass('predicted');
                                div.title = div.title + ' (Prognozuojama)'
                            }
                            month++;
                        }
                    });
                                                                                                                        
                    $('#status').css('display', 'none');
                });
        </script>
        <?php
    }

    /**
     * @param array $dates          [date]=>boolean is predicted
     * @param array $subdivisions   [code]=>name
     * @param array $time_groups1   [subdivision][date]=>TimeGroup
     * @param array $time_groups2   [subdivision][date]=>TimeGroup
     * @param $mode                 see TABLE_MODE_*
     */
    public static function linear_compare2($dates, $series, $time_groups1, $time_groups2, $mode = self::DIAGRAM_MODE_ADMINISTRATED, $width = 500, $height = 100) {
        global $liner_compare_unique_id;
        global $liner_compare_unique_sub_id;
        $liner_compare_unique_id++;
        ?><div class="php_diagram"><?
        foreach ($time_groups1 as $serie => $time_group) {
            $liner_compare_unique_sub_id++;
            $my_series = array();
            $my_series["compare1_$liner_compare_unique_id"] = $series[$serie];
            $my_series["compare2_$liner_compare_unique_id"] = $series[$serie] . ' (Skaiciuojant pakeitimus)';
            $my_time_groups = array();
            $my_time_groups["compare1_$liner_compare_unique_id"] = self::time_group_to_array($time_group, $mode);
            $my_time_groups["compare2_$liner_compare_unique_id"] = self::time_group_to_array($time_groups2[$serie], $mode);
            $name = htmlspecialchars($series[$serie]);
            echo "<div>$name:</div>";
            $colors = self::php_liner("compare_liner_$liner_compare_unique_sub_id.gif", $dates, $my_series, $my_time_groups, $mode, $width, $height);
        }
        ?>
            <div class="legend">
                <div class="legend_line_compare1_<?=$liner_compare_unique_id;?>" style="border-left: 10px solid #<?= reset($colors); ?>">Prieš pakeitimus</div>
                <div class="legend_line_compare2_<?=$liner_compare_unique_id;?>" style="border-left: 10px solid #<?= end($colors); ?>">Įskaičiuojant pakeitimus</div>
            </div>
        </div><?
    }

    private static function time_group_to_array($line, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $result = array();
        foreach ($line as $date => $time_group) {
            switch ($mode) {
                case self::DIAGRAM_MODE_TIME:
                    $value = $time_group->sum_time_used();
                    break;
                default:
                    $value = $time_group->sum_administrated();
            }
            $result[$date] = $value;
        }
        return $result;
    }

   

    /*
     * Paints a linear IS chart 
     * @param array $dates              [date]=>boolean is predicted
     * @param array $is_names           [code]=>name
     * @param array $is_time_groups     [subdivision][date]=>TimeGroup
     * @param $mode                     see DIAGRAM_MODE_*
     */

    public static function linear_is($dates, $is_names, $is_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $column_count = count($is_time_groups);
        $row_count = self::get_row_count($is_time_groups);
        ?>
        <script>
                var chart;
                $(document).ready(function() {
                    chart = new Highcharts.Chart(
        <?
        echo "{\n";
        echo self::generate_chart("linear_is_table", $row_count * 40) . ",\n";
        echo self::generate_colors() . ",\n";
        echo self::generate_title("") . ",\n";
        echo self::generate_subtitle("") . ",\n";
        echo self::generate_xAxis($dates) . ",\n";
        if ($mode == self::DIAGRAM_MODE_TIME) {
            echo self::generate_yAxis("Darbo laikas valandomis") . ",\n";
        } else {
            echo self::generate_yAxis("Paraišku skaicius") . ",\n";
        }
        echo self::generate_tooltip() . ",\n";
//echo self::generate_legend() . ",\n";
        echo self::generate_is_series($is_names, $is_time_groups, $mode) . "\n";
        echo " }";
        ?>);		
                });
        </script>
        <div id="linear_is_table"></div>
        <?php
    }

    // Functions for DOTTED table

    /*
     * Generating data for dotted sub table
     */

    private static function generate_sub_data($sub_names, $sub_time_groups, $mode) {
        $max_value = self::get_max_sub_value($sub_names, $sub_time_groups, $mode);

        if ($mode == self::DIAGRAM_MODE_ADMINISTRATED) {
            foreach ($sub_names as $sub_code => $sub_title) {
                echo "<tr>";
                echo "<td>$sub_code</td>";
                foreach ($sub_time_groups[$sub_code] as $time_group) {
                    $value = intval($time_group->sum_administrated());
                    if ($time_group->predicted) {
                        $class = 'class="predicted"';
                    } else {
                        $class = '';
                    }
                    echo '<td title="' . $value . '"' . $class . '>
                            <div class="dotted_diagram_element" style="width:'.self::get_radius($value, $max_value).'px; height:'.self::get_radius($value, $max_value).'px; background-color:'.self::get_color($value, $max_value).'; margin:auto;"></div>
                          </td>';
                }
                echo "</tr>";
            }
        } else {
            foreach ($sub_names as $sub_code => $sub_title) {
                echo "<tr>";
                echo "<td>$sub_code</td>";
                foreach ($sub_time_groups[$sub_code] as $time_group) {
                    $value = floatval($time_group->sum_time_used());
                    if ($time_group->predicted) {
                        $class = 'class="predicted"';
                    } else {
                        $class = '';
                    }
                    echo '<td title="' . $value . '"' . $class . '>
                            <div class="dotted_diagram_element" style="width:'.self::get_radius($value, $max_value).'px; height:'.self::get_radius($value, $max_value).'px; background-color:'.self::get_color($value, $max_value).'; margin:auto;"></div>
                          </td>';
                }
                echo "</tr>";
            }
        }
    }

    /*
     * Generating data for dotted is table
     */

    private static function generate_is_data($is_names, $is_time_groups, $mode) {
        $max_value = self::get_max_is_value($is_names, $is_time_groups, $mode);

        if ($mode == self::DIAGRAM_MODE_ADMINISTRATED) {
            foreach ($is_names as $is_code => $is_title) {
                echo "<tr>";
                echo "<td>$is_code</td>";
                foreach ($is_time_groups[$is_code] as $time_group) {
                    $value = intval($time_group->sum_administrated());
                    if ($time_group->predicted) {
                        $class = 'class="predicted"';
                    } else {
                        $class = '';
                    }
                    echo '<td title="' . $value . '"' . $class . '>
                            <div class="dotted_diagram_element" style="width:'.self::get_radius($value, $max_value).'px; height:'.self::get_radius($value, $max_value).'px; background-color:'.self::get_color($value, $max_value).'; margin:auto;"></div>
                          </td>';
                }
                echo "</tr>";
            }
        } else {
            foreach ($is_names as $is_code => $is_title) {
                echo "<tr>";
                echo "<td>$is_code</td>";
                foreach ($is_time_groups[$is_code] as $time_group) {
                    $value = floatval($time_group->sum_time_used());
                    if ($time_group->predicted) {
                        $class = 'class="predicted"';
                    } else {
                        $class = '';
                    }
                    echo '<td title="' . $value . '"' . $class . '>
                            <div class="dotted_diagram_element" style="width:'.self::get_radius($value, $max_value).'px; height:'.self::get_radius($value, $max_value).'px; background-color:'.self::get_color($value, $max_value).'; margin:auto;"></div>
                          </td>';
                }
                echo "</tr>";
            }
        }
    }

    /*
     * Gets max value from SUB array
     * @return $max
     */

    private static function get_max_sub_value($sub_names, $sub_time_groups, $mode) {
        $max = 0;
        if ($mode == self::DIAGRAM_MODE_ADMINISTRATED) {
            foreach ($sub_names as $sub_code => $sub_title) {
                foreach ($sub_time_groups[$sub_code] as $time_group) {
                    if ($time_group->sum_administrated() > $max) {
                        $max = $time_group->sum_administrated();
                    }
                }
            }
        } else {
            foreach ($sub_names as $sub_code => $sub_title) {
                foreach ($sub_time_groups[$sub_code] as $time_group) {
                    if ($time_group->sum_time_used() > $max) {
                        $max = $time_group->sum_time_used();
                    }
                }
            }
        }

        return $max;
    }

    /*
     * Gets max value from IS array
     * @return $max
     */

    private static function get_max_is_value($is_names, $is_time_groups, $mode) {
        $max = 0;
        if ($mode == self::DIAGRAM_MODE_ADMINISTRATED) {
            foreach ($is_names as $is_code => $is_title) {
                foreach ($is_time_groups[$is_code] as $time_group) {
                    if ($time_group->sum_n > $max) {
                        $max = $time_group->sum_n;
                    }
                }
            }
        } else {
            foreach ($is_names as $is_code => $is_title) {
                foreach ($is_time_groups[$is_code] as $time_group) {
                    if ($time_group->sum_time > $max) {
                        $max = $time_group->sum_time;
                    }
                }
            }
        }

        return $max;
    }

    /*
     * Gets radius of cyrcle depending on value
     * @return $radius
     */

    private static function get_radius($current_value, $max_value) {
        $radius = 1;
        if ($current_value != 0 && $max_value != 0) {
            $radius += ($current_value / $max_value) * 15;
        }

        return round($radius);
    }

    /*
     * Gets color depending on value
     * @return #xxxxxx color
     */

    private static function get_color($current_value, $max_value) {
        $value = round($current_value);
        $max_value = round($max_value);
        $color = "#";
        if ($current_value < ($max_value / 2)) {
            if ($max_value != 0) {
                $color_intensity = 67 + (124 * ($current_value / ($max_value / 2)));
                $color .= dechex(intval($color_intensity));
                $color .= "BF2F";
            } else {
                $color .= "43BF2F";
            }
        } else {
            if ($max_value != 0) {
                $current_value = $max_value - $current_value;
                $color_intensity = 47 + (144 * ($current_value / ($max_value / 2)));
                $color .= "BF" . dechex(intval($color_intensity));
                $color .= "2F";
            } else {
                $color .= "BF362F";
            }
        }

        return $color;
    }

    /*
     * Generating headers for dotted table
     */

    private static function generate_headers($dates) {
        echo "<tfoot><tr>";
        echo "<td></td>";
        foreach ($dates as $date => $is_forecasted) {
            echo "<td align='center'>" . substr($date, 0, 4) . "<br>" . substr($date, 5, 2) . "</td>";
        }
        echo "</tr></tfoot>";
    }

    // Functions for LINEAR chart

    /*
     * Generating linear chart
     * @return chart: {...}
     */

    private static function generate_chart($table_div, $width) {
        $generated_chart = "chart: {
            renderTo: '" . $table_div . "',
            defaultSeriesType: 'spline',
            marginRight: 20,
            width: " . $width . ",
            height: 330
            }";
        return $generated_chart;
    }

    /*
     * Generating default colors for lines
     * @return colors: {...}
     */

    private static function generate_colors() {
        $generated_colors = "colors: [
	'#4572A7', 
	'#AA4643', 
	'#89A54E', 
	'#80699B', 
	'#3D96AE', 
	'#DB843D', 
	'#92A8CD', 
	'#A47D7C', 
	'#B5CA92',
        '#5F5F5F',
        '#C0EA00',
        '#EA71E0',
        '#EB7070'
        ]";

        return $generated_colors;
    }

    /*
     * Generating title for linear chart
     * @return title: {...}
     */

    private static function generate_title($chart_title) {
        $generated_title = "title: {
            text: '" . $chart_title . "'
            }";
        return $generated_title;
    }

    /*
     * Generating subtitle for linear chart
     * @return subtitle: {...}
     */

    private static function generate_subtitle($chart_subtitle) {
        $generated_subtitle = "subtitle: {
            text: '" . $chart_subtitle . "'
            }";
        return $generated_subtitle;
    }

    /*
     * Generating xAxis for linear chart
     * @return xAxis: {...} 
     */

    private static function generate_xAxis($dates) {
        $prediction_starts = -0.5;
        $generated_xAxis = "xAxis: { 
            tickLength: 30,
            categories: ";
        $generated_xAxis .= self::generate_dates($dates, "linear", $prediction_starts) . ",
            plotBands: [{
                from: " . ($prediction_starts - 0.5) . ",
                to: " . ($prediction_starts + 12.0) . ",
                color: 'rgba(68, 170, 213, .2)'
            }]
            }";
        return $generated_xAxis;
    }

    /*
     * Generates yAxis for linear chart
     * @return yAxis: {...}
     */

    private static function generate_yAxis($axis_title) {
        $generated_yAxis = "yAxis: { 
            title : {
                text: '" . $axis_title . "'
                },
            min: 0,
            showFirstLabel: false,
            plotLines: [{
            value: 0,
            width: 1,
            color: '#808080' }]
            }";
        return $generated_yAxis;
    }

    /*
     * Generating tooltip for linear on chart points
     * @return tooltip: {...}
     */

    private static function generate_tooltip() {
        $generated_tooltip = "tooltip: {
            formatter: function() {
                return '<b>'+ this.series.name +'</b><br/>'+
                    this.x.toString().substring(0, 4) + '-' + this.x.toString().substring(5, 7) + ': '+ this.y;
                }
            }";
        // TODO: could be bugs with date
        return $generated_tooltip;
    }

    /*
     * Generating legend for linear chart
     * @return legend: {...} 
     */

    private static function generate_legend() {
        $generated_legend = "legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'top',
            x: -10,
            y: 100,
            borderWidth: 0
            }";
        return $generated_legend;
    }

    /**
     * Generating data for linear chart
     * 
     * @param $mode see DIAGRAM_MODE_*
     * @return series: {...}
     */
    private static function generate_sub_series($sub_names, $sub_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $generated_series = "series: [
                ";

        switch ($mode) {
            // Show administrated
            case self::DIAGRAM_MODE_ADMINISTRATED;
                foreach ($sub_names as $code => $title) {
                    $generated_series .= " { name: '" . $code . "',
                        data: [";
                    foreach ($sub_time_groups[$code] as $time_group) {
                        $generated_series .= $time_group->sum_administrated() . ",";
                    }
                    $generated_series = substr_replace($generated_series, "] },", -1);
                }
                break;
            // Time
            case self::DIAGRAM_MODE_TIME:
                foreach ($sub_names as $code => $title) {
                    $generated_series .= " { name: '" . $code . "',
                        data: [";
                    foreach ($sub_time_groups[$code] as $time_group) {
                        $generated_series .= $time_group->sum_time_used() . ",";
                    }
                    $generated_series = substr_replace($generated_series, "] },", -1);
                }
                break;
        }

        $generated_series = substr_replace($generated_series, "]", -1);
        return $generated_series;
    }

    private static function generate_is_series($is_names, $is_time_groups, $mode = self::DIAGRAM_MODE_ADMINISTRATED) {
        $generated_series = "series: [
                ";

        // Different cycles for performance
        if ($mode == self::DIAGRAM_MODE_TIME) {
            foreach ($is_names as $code => $title) {
                $generated_series .= " { name: '" . $code . "',
                    data: [";
                foreach ($is_time_groups[$code] as $time_group) {
                    $generated_series .= $time_group->sum_time . ",";
                }
                $generated_series = substr_replace($generated_series, "] },", -1);
            }
        } else {
            foreach ($is_names as $code => $title) {
                $generated_series .= " { name: '" . $code . "',
                    data: [";
                foreach ($is_time_groups[$code] as $time_group) {
                    $generated_series .= $time_group->sum_n . ",";
                }
                $generated_series = substr_replace($generated_series, "] },", -1);
            }
        }

        $generated_series = substr_replace($generated_series, "]", -1);
        return $generated_series;
    }

    /*
     * Generating dates for table
     */

    private static function generate_dates($dates, $type, &$prediction_starts = null) {
        $prediction_starts = -0.5;
        $generated_dates = "[";
        if ($type == "dotted") {
            foreach ($dates as $date => $is_forecast) {
                $generated_dates .= '"' . substr($date, 0, 4) . "\\n" . substr($date, 5, 2) . '",';
            }
        } else {
            $month_count = 0.0;
            foreach ($dates as $date => $is_forecast) {
                if ($prediction_starts == -0.5 && $is_forecast == 1) {
                    $prediction_starts = $month_count;
                }
                $generated_dates .= '"' . substr($date, 0, 4) . " " . substr($date, 5, 2) . '",';
                $month_count += 1.0;
            }
        }

        $generated_dates = substr_replace($generated_dates, "]", -1);
        return $generated_dates;
    }

    /*
     * Returns how many different dates are in <$is_time_groups>
     * @return row_count
     */

    private static function get_row_count($time_groups) {
        $row_count = 0;
        foreach ($time_groups as $is_code_data) {
            $row_count = count($is_code_data);
            break;
        }
        return $row_count;
    }

}